﻿#if WINDOWS_PHONE
#else
using Microsoft.Xna.Framework.Net;

namespace JGLib.Net
{
    /*
     * To create a base class of Message:
     *   1. Create a static constructor that calls Message.RegisterMessageHeader(Message)
     *      with an instance of the base class.
     *   2. Create an instance constructor that calls the Message instance constructor by
     *      using base(object).
     *   3. Override the GetHeader() method, which should return a byte based on the
     *      instance's Type field. The return value of this method should be unique to
     *      this message class.
     *   4. Optional: Override the Write(PacketWriter) method, which should write any
     *      information pertaining to the message into the PacketWriter.
     *      NOTE: The header byte is already written to the PacketWriter before Write(
     *      PacketReader) is called.
     *   5. Override the Read(PacketReader), which should return an object[] containing
     *      any necessary information read from the PacketReader.
     *      NOTE: The header byte is already read and removed from the stream before
     *      Read(PacketReader) is called.
     */
    public abstract class Message
    {
        public object Type { get; set; }
        private static Message[] MessageFromHeader;

        static Message()
        {
            Message.MessageFromHeader = new Message[256];
        }
        protected static void RegisterMessageHeader(Message message)
        {
            byte header = message.GetHeader();
            MessageFromHeader[header] = message;
        }

        protected Message(object type)
        {
            this.Type = type;
        }

        public void WriteMessage(PacketWriter writer, LocalNetworkGamer gamer, SendDataOptions options)
        {
            writer.Write(this.GetHeader());
            this.Write(writer);
            gamer.SendData(writer, options);
        }
        public static object[] ReadMessage(PacketReader reader)
        {
            byte header = reader.ReadByte();
            Message messageReader = Message.MessageFromHeader[header];
            return messageReader.Read(reader);
        }        

        protected abstract byte GetHeader();
        protected virtual void Write(PacketWriter writer) { }

        protected abstract object[] Read(PacketReader reader);
    }
}
#endif